package local.blueheart.data.springdatademo.service.impl;

import local.blueheart.data.springdatademo.domain.config.ApplicationDO;
import local.blueheart.data.springdatademo.domain.config.ArchiveSourceDO;
import local.blueheart.data.springdatademo.domain.config.ItemDO;
import local.blueheart.data.springdatademo.domain.config.ModuleDO;
import local.blueheart.data.springdatademo.repository.config.ApplicationRepository;
import local.blueheart.data.springdatademo.repository.config.ArchiveSourceRepository;
import local.blueheart.data.springdatademo.repository.config.ItemRepository;
import local.blueheart.data.springdatademo.repository.config.ModuleRepository;
import local.blueheart.data.springdatademo.service.XmlConfigService;
import local.blueheart.data.springdatademo.util.Dom4jUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.URL;
import java.util.List;


@Service
public class XmlConfigServiceImpl implements XmlConfigService {

    private static final Logger LOGGER = LoggerFactory.getLogger(XmlConfigServiceImpl.class);

    @Autowired
    private ArchiveSourceRepository archiveSourceRepository;

    @Autowired
    private ApplicationRepository applicationRepository;

    @Autowired
    private ModuleRepository moduleRepository;

    @Autowired
    private ItemRepository itemRepository;

    @Override
    public void initConfig(URL configFileURL) {
        try {
            Document document = Dom4jUtil.parse(configFileURL);
            String version = document.selectSingleNode(Dom4jUtil.ARCHIVE_SOURCE_VERSION_EXPRESSION).getStringValue();
            String currentVersion = currentVersion();
            if(version.equals(currentVersion)){
                return;
            }
            clearAllConfig();
            //ArchiveSourceDO
            Node archiveNode = document.selectSingleNode(Dom4jUtil.ARCHIVE_SOURCE_EXPRESSION);
            ArchiveSourceDO archiveSourceDO = Dom4jUtil.getArchiveSourceDO(archiveNode);
            saveArchiveSourceConfig(archiveSourceDO);
            //ApplicationList
            Element aElement = (Element) archiveNode;
            for(int i=0;i<aElement.nodeCount();i++){
                Node appNode = aElement.node(i);
                if(appNode instanceof Element) {
                    ApplicationDO applicationDO = Dom4jUtil.getApplicationDO(appNode);
                    applicationDO.setArchiveSourceDO(archiveSourceDO);
                    Element appElement = (Element) appNode;
                    for (int j = 0; j < appElement.nodeCount(); j++) {
                        Node moduleNode = appElement.node(j);
                        if(moduleNode instanceof Element) {
                            ModuleDO moduleDO = Dom4jUtil.getModuleDO(moduleNode);
                            saveModuleConfig(moduleDO);
                            Element moduleElement = (Element) moduleNode;
                            for (int k = 0; k < moduleElement.nodeCount(); k++) {
                                Node itemNode = moduleElement.node(k);
                                if(itemNode instanceof Element) {
                                    ItemDO itemDO = Dom4jUtil.getItemDO(itemNode);
                                    itemDO.setModuleDO(moduleDO);
                                    saveItemConfig(itemDO);
                                }
                            }
                            applicationDO.setModuleDO(moduleDO);
                            saveApplicationConfig(applicationDO);
                        }
                    }
                    //saveApplicationConfig(applicationDO);
                }
            }

        } catch (DocumentException e) {
           LOGGER.error("初始化配置失败",e);
        }
    }

    @Override
    public String currentVersion() {
        List<ArchiveSourceDO> archiveSourceRepositories = archiveSourceRepository.findAll();
        if(archiveSourceRepositories.isEmpty()){
            return "0";
        }else{
            return archiveSourceRepositories.get(0).getConfigVersion();
        }
    }

    @Transactional
    @Override
    public void clearAllConfig() {
        itemRepository.deleteAll();
        applicationRepository.deleteAll();
        moduleRepository.deleteAll();
        archiveSourceRepository.deleteAll();
    }

    @Transactional
    @Override
    public void saveArchiveSourceConfig(ArchiveSourceDO archiveSourceDO) {
        archiveSourceRepository.save(archiveSourceDO);
    }

    @Transactional
    @Override
    public void saveApplicationConfig(ApplicationDO applicationDO) {
        applicationRepository.save(applicationDO);
    }

    @Transactional
    @Override
    public void saveModuleConfig(ModuleDO moduleDO) {
        moduleRepository.save(moduleDO);
    }
    @Transactional
    @Override
    public void saveItemConfig(ItemDO itemDO) {
        itemRepository.save(itemDO);
    }

    @Override
    public List<ApplicationDO> getAllApplication() {
        return applicationRepository.findAll();
    }
}
